/**
 * Google Maps Canvas View Gadget.
 * (C) 2008 BonstioNet Limited.
 * @constructor
 * @param containerId - id of the container in which to draw the gadget.
 */

MapGadget = function(mapContainerId) {
    this.mapContainerId_ = mapContainerId;

    this.prefs_ = new _IG_Prefs();

    this.map_ = null;
    this.useDragZoom = false;

    this.mapLocation_ = this.prefs_.getString("mapLocation");
    this.mapZoom_ = this.prefs_.getInt("mapZoom");
    this.mapType_ = this.prefs_.getString("mapType");

    this.showImages_ = MapGadget.SHOW_IMAGES;
};

MapGadget.SHOW_IMAGES = false;

/**
 * Renders the actual gadget. This method is not called until page load. Hence we place our static variables in here
 * so that the Google Maps API has loaded when they are declared; they cannot go in the constructor as this is invoked
 * during subclass inheritance.
 */
MapGadget.prototype.render = function() {
    if (!GBrowserIsCompatible()) {
        alert('Your browser is to antiquated to run Google Maps.')   
    } else {
        // Define which controls are shown in which view.
        MapGadget.MAP_CONTROLS_ = [
            [GSmallZoomControl,GMenuMapTypeControl,GOverviewMapControl],
            [GLargeMapControl, GMapTypeControl]];
        // Define what map types are available for this gadget.
        MapGadget.MAP_TYPES_ = [G_HYBRID_MAP, G_NORMAL_MAP, G_SATELLITE_MAP, G_PHYSICAL_MAP];
        this.initMap_();
    }
};

/**
 * Init and render the Google Map within the container.
 */
MapGadget.prototype.initMap_ = function() {
    var GMapOptions = {mapTypes: MapGadget.MAP_TYPES_};
    this.map_ = new GMap2(
        _gel(this.mapContainerId_),
        GMapOptions);
    this.map_.setCenter(
        this.getLatLongFromMapLocation(this.mapLocation_),
        this.mapZoom_,
        MapGadget.MAP_TYPES_[this.mapType_]);
    GEvent.addListener(
        this.map_,
        'maptypechanged',
        throttle(
                bind(this.onMapTypeChanged_, this),
                1500));
    GEvent.addListener(
        this.map_,
        'moveend',
        throttle(
                bind(this.onMapMoved_, this), 
                1500));
    if (this.useDragZoom) {
        this.map_.addControl(new DragZoomControl());
    }

    for (var i=0, view; view = MapGadget.MAP_CONTROLS_[0][i]; i++) {
        this.map_.addControl(new view());
    }

    window.onresize = bind(function(){
        var infoWindow = this.map_.getInfoWindow();
        if (infoWindow && !infoWindow.isHidden()) {
            this.navigate(0);
        }
    }, this);
};

/**
 * Method invoked when the map has been panned or zoomed; saves the current position and zoom level.
 */
MapGadget.prototype.onMapMoved_ = function() {
    var center = this.map_.getCenter();
    this.prefs_.set(
        'mapLocation', center.toUrlValue(),
        'mapZoom', this.map_.getZoom());
};

/**
 * Method invoked when the map type has been changed; save the newly selected map type.
 */
MapGadget.prototype.onMapTypeChanged_ = function() {
    var mapType = MapGadget.MAP_TYPES_.indexOf(this.map_.getCurrentMapType());
    this.prefs_.set('mapType', mapType);
};

/**
 * Converts a lat/long string into a GLatLng object.
 * TODO find suspected bug in here - url encoding check?
 * @param mapLocation - comma separated lattitude and longitude string.
 */
MapGadget.prototype.getLatLongFromMapLocation = function(mapLocation) {
    var coords = mapLocation.split(",");
    return new GLatLng(parseFloat(coords[0], 10), parseFloat(coords[1], 10));
};